package com.coincalf.web;

import
        com.coincalf.dto.ForexAreaMarketDTO;
import com.coincalf.dto.MarketDTO;
import com.coincalf.framework.constants.Constant;
import com.coincalf.framework.dto.ForexMarketDTO;
import com.coincalf.framework.enums.KlineType;
import com.coincalf.framework.enums.MarketType;
import com.coincalf.framework.http.Response;
import com.coincalf.framework.security.UserDetails;
import com.coincalf.framework.utils.GsonUtil;
import com.coincalf.service.MarketService;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @Description: 创新交易市场Controller
 * @Author: Chen Long
 * @Date: Created in 2018/5/14 上午10:01
 * @Modified by: Chen Long
 */
@RestController
@RequestMapping("/forex/market")
@Slf4j
@Api(value = "创新交易市场", description = "创新交易市场 REST API")
public class ForexMarketController implements Constant {

    @Autowired
    private MarketService marketService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private CommonController commonController;

    /**
     * 首页交易市场信息
     *
     * @return
     */
    @GetMapping
    @ApiOperation(value = "FOREX-MARKET-001 首页市场信息", notes = "首页市场信息", httpMethod = "GET")
    @ResponseBody
    public Object market() {
        return marketService.queryForexMarkets();
    }

    /**
     * 个人收藏交易市场信息
     *
     * @return
     */
    //@PreAuthorize("isAuthenticated()")
    @GetMapping("/favorite")
    @ApiOperation(value = "MARKET-002 个人收藏交易市场信息", notes = "个人收藏交易市场信息", httpMethod = "GET")
    @ResponseBody
    public Object favorite(HttpServletRequest request) {
        Long userId = commonController.getUserId(request);
        List<ForexAreaMarketDTO> forexAreaMarket = marketService.queryFavoriteForexMarkets(userId);
        return Response.ok(forexAreaMarket);
    }

    /**
     * 获取K线数据
     *
     * @param symbol   获取K线数据请求参数
     * @param lintType 获取K线数据请求参数
     * @return
     */
    @GetMapping(value = "/kline/{symbol}/{lintType}")
    @ApiOperation(value = "FOREX-MARKET-003 币币交易K线数据", notes = "lineType取值范围<br/>" +
            "5sec: 5秒钟<br />" +
            "1min: 1分钟<br />" +
            "5min: 5分钟<br />" +
            "15min: 15分钟<br />" +
            "30min: 30分钟<br />" +
            "1hour: 1小时<br />" +
            "2hour: 2小时<br />" +
            "4hour: 4小时<br />" +
            "6hour: 6小时<br />" +
            "12hour: 12小时<br />" +
            "1day: 1天<br />" +
            "1week: 1周<br />" +
            "1mon: 1月<br />" +
            "1year: 1年<br />", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "symbol", value = "交易对标识符", required = true, dataType = "String", paramType = "path"),
            @ApiImplicitParam(name = "lintType", value = "K线类型", required = true, dataType = "String", paramType = "path")
    })
    @ResponseBody
    public Object kline(
            @PathVariable("symbol") String symbol,
            @PathVariable("lintType") String lintType
    ) {
        String redisKey = new StringBuffer(REDIS_KEY_FOREX_KLINE).append(symbol).append(":").append(lintType).toString();
        List<Object> kline = redisTemplate.opsForList().range(redisKey, 0, 999);
        Collections.reverse(kline);
        return Response.ok(GsonUtil.toJson(kline));
    }

    /**
     * 获取交易对行情数据
     *
     * @param symbol 交易对标识符
     * @return
     */
    @GetMapping(value = "/ticker/{symbol}")
    @ApiOperation(value = "FOREX-MARKET-004 币币交易实时行情", notes = "币币交易实时行情", httpMethod = "GET")
    @ApiImplicitParam(name = "symbol", value = "交易对标识符", required = true, dataType = "String", paramType = "path")
    @ResponseBody
    public Object ticker(@PathVariable("symbol") String symbol) {
        String redisKey = new StringBuffer(REDIS_KEY_FOREX_KLINE).append(symbol).append(":").append(KlineType.FIVE_SECONDS).toString();
        Object kline = redisTemplate.opsForList().index(redisKey, 0);
        return Response.ok(GsonUtil.toJson(kline));
    }

    /**
     * 根据marketIds获取创新交易市场
     *
     * @return
     */
    @ApiIgnore
    @PostMapping("/queryForexMarkets")
    public Collection<ForexMarketDTO> queryTradeMarkets() {
        return marketService.FOREX_MARKET_CACHE_INSTANCE().asMap().values();
    }

    /**
     * 根据marketIds获取创新交易市场
     *
     * @return
     */
    @ApiIgnore
    @PostMapping("/queryForexMarketsByIds")
    public ImmutableList<ForexMarketDTO> queryTradeMarketsByIds(String marketIds) {
        String[] ids = marketIds.split(",");
        List<Long> keys = new ArrayList<>();
        for (String id : ids) {
            keys.add(Long.valueOf(id));
        }
        ImmutableMap<Long, ForexMarketDTO> tradeMarketDTOImmutableMap = marketService.FOREX_MARKET_CACHE_INSTANCE().getAllPresent(keys);
        return tradeMarketDTOImmutableMap.values().asList();
    }

    /**
     * 刷新创新交易市场
     *
     * @param marketId 交易对ID
     * @return
     */
    @GetMapping("/refresh/{marketId}")
    public boolean refreshMarket(@PathVariable("marketId") Long marketId) {
        marketService.FOREX_MARKET_CACHE_INSTANCE().refresh(marketId);
        return true;
    }

    /****************************************** 微服务 *******************************************************/
    /**
     * 获取所有创新交易市场
     *
     * @return
     */
    @ApiIgnore
    @GetMapping("/all")
    public List<MarketDTO> tradeMarkets() {
        return marketService.queryByType(MarketType.FOREX);
    }

}
